{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "class NaryNode:\n",
    "    indent = '  '\n",
    "\n",
    "    def __init__(self, value) -> None:\n",
    "        self.value = value\n",
    "        self.children = []\n",
    "\n",
    "    def add_child(self, new_node):\n",
    "        self.children.append(new_node)\n",
    "\n",
    "    # my solution\n",
    "    # def __str__(self, level = 0):\n",
    "    #     result = f\"{self.value}:\\n\"\n",
    "    #     level += 1\n",
    "    #     for child in self.children:\n",
    "    #         result += f\"{self.indent * level}{child.__str__(level)}\"\n",
    "    #     return result\n",
    "    \n",
    "    # the solution's __str__\n",
    "    def __str__(self, level=0):\n",
    "        result = level * NaryNode.indent + f'{self.value}:\\n'\n",
    "        for child in self.children:\n",
    "            result += child.__str__(level + 1)\n",
    "        return result\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "NaryNode class is sometimes easier to work with than the BinaryNode class because it treats every child in the same way. You need to write separate pieces of code to recursively work with the left and right children of a BinaryNode object. In contrast **the NaryNode class can manipulate its children in a loop.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Build a test tree.\n",
    "#      Root\n",
    "#        |\n",
    "#     +--+--+\n",
    "#     A  B  C\n",
    "#     |     |\n",
    "#    +-+    +\n",
    "#    D E    F\n",
    "#    |      |\n",
    "#    +     +-+\n",
    "#    G     H I\n",
    "\n",
    "root_node = NaryNode(\"Root\")\n",
    "a_node = NaryNode(\"A\")\n",
    "b_node = NaryNode(\"B\")\n",
    "c_node = NaryNode(\"C\")\n",
    "d_node = NaryNode(\"D\")\n",
    "e_node = NaryNode(\"E\")\n",
    "f_node = NaryNode(\"F\")\n",
    "g_node = NaryNode(\"G\")\n",
    "h_node = NaryNode(\"H\")\n",
    "i_node = NaryNode(\"I\")\n",
    "\n",
    "root_node.add_child(a_node)\n",
    "root_node.add_child(b_node)\n",
    "root_node.add_child(c_node)\n",
    "a_node.add_child(d_node)\n",
    "a_node.add_child(e_node)\n",
    "c_node.add_child(f_node)\n",
    "d_node.add_child(g_node)\n",
    "f_node.add_child(h_node)\n",
    "f_node.add_child(i_node)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Root:\n",
      "  A:\n",
      "    D:\n",
      "      G:\n",
      "    E:\n",
      "  B:\n",
      "  C:\n",
      "    F:\n",
      "      H:\n",
      "      I:\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(root_node)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "A:\n",
      "  D:\n",
      "    G:\n",
      "  E:\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(a_node)"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "e63faaf9bc27d837377622cad56f3d439b9a97e8fa476559128293c868ce68e0"
  },
  "kernelspec": {
   "display_name": "Python 3.9.7 64-bit ('word_database': conda)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
